#include "qsamplesmhswidget.h"

#include <eikenv.h>
// skin support
#include <aknsskininstance.h>
#include <aknsutils.h>
#include <aknsbasicbackgroundcontrolcontext.h>
#include <aknsdrawutils.h>

const QString sw_type = "wideimage";
const QString sw_name = "[Ex] [Qt] Signal Level";
const QString sw_id = "0xE59C7E13_2"; //can be any unique string

const QString sw_image ("image1");


QSampleSMHSWidget::QSampleSMHSWidget(QObject *parent) :
    QObject(parent), iFbsBitmap(0)
{
    iWidget  = QHSWidget::create(sw_type, sw_name, sw_id, this);
    connect(iWidget, SIGNAL(handleEvent(QHSWidget*, QHSEvent)), this, SLOT(handleEvent(QHSWidget*, QHSEvent) ));
    connect(iWidget, SIGNAL(handleItemEvent(QHSWidget*, QString, QHSItemEvent)), this, SLOT(handleItemEvent(QHSWidget*, QString, QHSItemEvent)));


    for (int i=0; i<KNumberOfMeasurements; i++)
        iMeasurements[i]=  rand()%8; //rand from stdlib

    iSystemNetworkInfo = new QSystemNetworkInfo(this);
    connect (iSystemNetworkInfo, SIGNAL(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode, int)), this, SLOT(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode,int)));

}

void QSampleSMHSWidget::RegisterWidget()
{

    iWidget->RegisterWidget();

}

void QSampleSMHSWidget::handleEvent(QHSWidget*, QHSEvent aEvent )
{
    switch(aEvent)
    {
    case EResume:
    {
        // homescreen is back in the foreground,so you can show new stuff
        iCanPublish = true;
        // force a refresh if needed
        // e.g. if the active theme has been changed or signal update
        // happend during suspend mode
        if(iNeedUpdate)
        {
            ChangeWidgetValues();
            iWidget->PublishWidget();
            iNeedUpdate = false;
        }
    };
        break;
    case EActivate:
    {
        // widget is added to the homescreen
        // make sure it has content
        SignalLevelChanged(-1);
    };
    case EDeactivate:
    case ESuspend:
    default:
        iCanPublish = false;
    }

}

void QSampleSMHSWidget::handleItemEvent(QHSWidget*, QString ,
                                        QHSItemEvent )
{
    if(iCanPublish) RunAnimationTest();
}

void QSampleSMHSWidget::networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode, int aBars)
{
    if (aBars >= 0)
    {//QtMobility returns aBars (-1, 0..100). Should be 0..8
        aBars = aBars / 10 % 8;
        SignalLevelChanged(aBars);
    }
}

void QSampleSMHSWidget::DrawImage()
{
    TRAP_IGNORE(DrawImageL());
}

void QSampleSMHSWidget::DrawImageL()
{

    //bitmap can be created in constructor. Device and context can be declared as class members. I just want isolate Symbian C++ code as much as possible.
    //Btw, there are methods in QPixmap for conversion in\to CFbsBitmap
    if (!iFbsBitmap)
    {
        iFbsBitmap = new (ELeave) CFbsBitmap;
        User::LeaveIfError( iFbsBitmap->Create(TSize(312,82),
                                              CEikonEnv::Static()->DefaultDisplayMode()));
    }


    CFbsBitmapDevice * wideFrameDevice = CFbsBitmapDevice::NewL(iFbsBitmap);
    CleanupStack::PushL(wideFrameDevice);
    CFbsBitGc* wideFrameContext(NULL);
    User::LeaveIfError(wideFrameDevice->CreateContext(wideFrameContext));
    CleanupStack::PushL(wideFrameContext);

    // get the current template
    MAknsSkinInstance* skin = AknsUtils::SkinInstance();

    // widget position unknown, using arbitrary rectangle
    // works OK only with plain theme backgrounds
    TRect rect(0,0,312,82);

    // fetch background from the current theme
    CAknsBasicBackgroundControlContext* bgContext;
    bgContext = CAknsBasicBackgroundControlContext::NewL(
                KAknsIIDQsnBgAreaMainIdle,rect,ETrue);
    AknsDrawUtils::Background( skin, bgContext,
                               (CWindowGc&)*wideFrameContext, rect);
    delete bgContext;



    TRgb textColor;
    // fetch the text color from the current scheme
    AknsUtils::GetCachedColor( skin, textColor,
                               KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG20 );

    wideFrameContext->SetPenStyle(CGraphicsContext::ESolidPen);
    wideFrameContext->SetPenColor(textColor);
    wideFrameContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
    wideFrameContext->SetBrushColor(textColor);

    // draw the signal bars on the bitmap
    for (int i=0; i<KNumberOfMeasurements; i++)
    {
        for(int j=0; j<iMeasurements[i]; j++)
        {
            // magic numbers here :)
            TRect rect(8+13*i,63-9*j,18+13*i,70-9*j);
            wideFrameContext->DrawRect(rect);
        }
    }

    CleanupStack::PopAndDestroy(2, wideFrameDevice);
}


void QSampleSMHSWidget::SignalLevelChanged(int aBars)
{


    // handle only real values received from the signal monitor
    // negative aBars are passed to this method only when a repaint of the
    // old data is desired.
    if(aBars >= 0)
    {
        // advance list of measurements
        for (int i=0; i<KNumberOfMeasurements-1; i++)
            iMeasurements[i]=iMeasurements[i+1];
        // add current value at the end
        iMeasurements[KNumberOfMeasurements-1] = aBars;
    }

    // there's no point publishing this data if the home screen is not in the
    // foreground or if the widget is not selected on the home screen
    // unless aBars < 0 which means a forced update is intended
    if(iCanPublish || aBars<0)
    {
        DrawImage();

        // set this bitmap to the template item
        ChangeWidgetValues();

        // commit the bitmap to the home screen
        iWidget->PublishWidget();

        // publishing was done
        iNeedUpdate = EFalse;
    }
    else
        // can't publish the changed data now, remember to update
        // as soon as possible
        iNeedUpdate = ETrue;


}

void QSampleSMHSWidget::ChangeWidgetValues( )
{
    if (!iFbsBitmap) return;

    try{
        if (iFbsBitmap)
            iWidget->SetItem(sw_image, iFbsBitmap->Handle());
    }
    catch ( ... ) {
        delete iFbsBitmap;
        iFbsBitmap = 0;
        throw;
    }

}

void QSampleSMHSWidget::RunAnimationTest()
{
    for(int i=0; i<100; i++)
    {
        SignalLevelChanged(i%8);
    }
}

QSampleSMHSWidget::~QSampleSMHSWidget()
{
    if (iFbsBitmap) delete iFbsBitmap;
}
